/*  This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or (at
    your option) any later version.
    For more details, see the GNU Lesser General Public License (www.fsf.org
    or the COPYING file somewhere in the package)
 */

#ifndef OSGI_ACTIVATOR_HH
#define OSGI_ACTIVATOR_HH

#include "OSGi.hh"

/*! @file OSGi/Activator.hh
    @brief Class OSGi::Activator header.
    @author @ref Guillaume_Terrissol
    @date 12th December 2009 - 26th May 2013
    @note This file is distributed under the LGPL license.
    Refer to the file COPYING (or http://www.fsf.org) for more information.
 */

#include <map>
#include <memory>
#include <string>

#include "Context.hh"

namespace OSGi
{
//------------------------------------------------------------------------------
//                             Activator Base Class
//------------------------------------------------------------------------------

    /*! @brief Bundle Activator.
        @version 0.9

        A class inheriting this one shall be defined in every bundle to do all
        needed initialization and finalization (in doStart() and doStop() methods
        respectively).
        @sa @ref OSGi_Create_Activator_Page
     */
    class OSGI_EXPORT Activator
    {
    public:
        //! @name Constructor & destructor
        //@{
                Activator();                        //!< Default constructor
virtual         ~Activator() = 0;                   //!< Destructor.
        //@}
        //! @name Interface
        //@{
        void    start(Context::Ptr pContext);       //!< Launching.
        void    stop(Context::Ptr pContext);        //!< Halting.
        //@}

    private:
        //! @name Implementation
        //@{
virtual void    doStart(Context::Ptr pContext) = 0; //!< Launching.
virtual void    doStop(Context::Ptr pContext) = 0;  //!< Halting.
        //@}
    };
}


//------------------------------------------------------------------------------
//                              Macros
//------------------------------------------------------------------------------

/*! Activator declaration beginning macro.
 */
#define OSGI_REGISTER_ACTIVATORS()                                      \
extern "C" OSGI_EXPORT OSGi::Activator* getActivator(const char* name)  \
{                                                                       \
    using Ptr = std::shared_ptr<OSGi::Activator>;                       \
    static std::map<std::string, Ptr>  sActivators =                    \
    {


/*! Activator registering macro.
    @param Class Activator class name (fully qualified)
 */
#define OSGI_DECLARE_ACTIVATOR(Class)   \
        { #Class, Ptr(new Class()) },


/*! Activator declaration ending macro.
 */
#define OSGI_END_REGISTER_ACTIVATORS()          \
        { "", Ptr() }                           \
    };                                          \
                                                \
    auto lActivator = sActivators.find(name);   \
    if (lActivator != end(sActivators))         \
    {                                           \
        return lActivator->second.get();        \
    }                                           \
    else                                        \
    {                                           \
        return nullptr;                         \
    }                                           \
}

#endif  // OSGI_ACTIVATOR_HH
